package engine;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

import com.threed.jpct.FrameBuffer;
import com.threed.jpct.Interact2D;
import com.threed.jpct.Object3D;
import com.threed.jpct.Primitives;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.Texture;
import com.threed.jpct.World;

import font.GLFont;

public class Ship implements IEntity {
	//LOGIC FIELDS
	private Planet source;
	private Planet destination;
	private int cargo;
	private float speed = .1f;
	private Ownership owner;
	
	//RENDER FIELDS
	private SimpleVector currentPosition;
	private SimpleVector jumpDistance;
	private SimpleVector sourceOrbit;
	private SimpleVector destinationOrbit;
	private float distance;
	private Object3D shipObject;
	private Object3D labelHandler;
	
	private Texture cargoBackgroundTexture;
	
	private static final GLFont font = new GLFont(new Font("Arial", Font.BOLD, 15));
	
	private final float LABEL_HEIGHT = 5.0f;
	
	private static final Color ENEMY_LABEL_BG_COLOR = new Color(255, 64, 64);
	private static final Color PLAYER_LABEL_BG_COLOR = new Color(0, 184, 245);

	public Ship(World world, Planet src, Planet dest, int cargo){
		source = src;
		destination = dest;
		shipObject = Primitives.getBox(1, 1);
		this.cargo = cargo;
		
		labelHandler = Object3D.createDummyObj();
		labelHandler.translate(0, -LABEL_HEIGHT, 0);
		labelHandler.addParent(shipObject);
		
		calculateSourceOrbit();
		calculateDestinationOrbit();
		distance = sourceOrbit.distance(destinationOrbit);
		calculateJumpDistance();
		shipObject.translate(sourceOrbit);
		currentPosition = new SimpleVector(sourceOrbit.x, sourceOrbit.y, sourceOrbit.z);
		world.addObject(shipObject);
		source.setPoints(source.getPoints() - cargo);
	}
	
	public int getCargo(){
		return cargo;
	}
	
	public Ownership getOwner(){
		return owner;
	}
	
	public void setOwner(Ownership owner){
		Color bgColor = null;
		if(owner == Ownership.PLAYER)
			bgColor = PLAYER_LABEL_BG_COLOR;
		else if(owner == Ownership.ENEMY)
			bgColor = ENEMY_LABEL_BG_COLOR;
		cargoBackgroundTexture = new Texture(32, 32, bgColor);
		this.owner = owner;
	}
	
	@Override
	public void onInit(World world, FrameBuffer buffer) {
		
	}
	
	public void destroy(World world){
		if(destination.getOwner() == owner){
			destination.setPoints(destination.getPoints() + cargo);
		} else {
			int points = destination.getPoints() - cargo;
			if(points <= 0){
				points = -points;
				destination.setOwner(owner);
			}
			destination.setPoints(points);
		}
		
		//destination.setPoints(destination.getPoints() + cargo);
		if(shipObject != null)
			world.removeObject(shipObject);
	}
	
	public boolean isShipArrived(){
		if(sourceOrbit.distance(currentPosition) < distance){
			return false;
		}
		return true;
	}
	
	@Override
	public void onUpdate(World world, FrameBuffer buffer) {
		if(!isShipArrived()){
			currentPosition.add(jumpDistance);
			shipObject.translate(jumpDistance);
		}
	}
	
	public void onRenderUpdate(World world, FrameBuffer buffer){
		if(true){
			SimpleVector labelHandlerProjection = Interact2D.projectCenter3D2D(world.getCamera(), buffer, labelHandler);
			
			if (labelHandlerProjection != null){
				String cargoString = Integer.toString(cargo);
				Dimension d = font.getStringBounds(cargoString);
				buffer.blit(cargoBackgroundTexture, 0, 0, (int) (labelHandlerProjection.x - d.getWidth() / 2) - 2,
						(int) labelHandlerProjection.y, (int)d.getWidth() + 4, (int)d.getHeight(), false);
				font.blitString(buffer, cargoString, (int) labelHandlerProjection.x - d.width / 2, (int) (labelHandlerProjection.y + d.getHeight() - 4), 100, Color.BLACK);
			}
		}
	}
	
	private void calculateJumpDistance(){
		jumpDistance = new SimpleVector();
		jumpDistance.x = speed / distance * (destinationOrbit.x - sourceOrbit.x);
		jumpDistance.y = speed / distance * (destinationOrbit.y - sourceOrbit.y);
		jumpDistance.z = speed / distance * (destinationOrbit.z - sourceOrbit.z);
	}
	
	private void calculateSourceOrbit(){
		sourceOrbit = new SimpleVector();
		sourceOrbit.x = source.getPosition().x + source.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().x - source.getPosition().x);
		sourceOrbit.y = source.getPosition().y + source.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().y - source.getPosition().y);
		sourceOrbit.z = source.getPosition().z + source.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().z - source.getPosition().z);
	}
	
	private void calculateDestinationOrbit(){
		destinationOrbit = new SimpleVector();
		destinationOrbit.x = destination.getPosition().x - destination.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().x - source.getPosition().x);
		destinationOrbit.y = destination.getPosition().y - destination.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().y - source.getPosition().y);
		destinationOrbit.z = destination.getPosition().z - destination.getRadius()/source.getPosition().distance(destination.getPosition())*(destination.getPosition().z - source.getPosition().z);
	}
}
